#pragma once

#include "Buffer.h"
#include "Callbacks.h"
#include "EventLoop.h"
#include "InetAddress.h"
#include "LoopThreadPool.h"
#include "TcpConnection.h"

#include <atomic>
#include <memory>
#include <string>
#include <unordered_map>

#include "Acceptor.h"

class TcpServer {
private:
    void DefaultConnection(const TcpConnectionPtr&);
    void DefaultMessage(const TcpConnectionPtr&);

public:
    TcpServer(EventLoop* loop, InetAddress address, std::string name);

    void SetConnectionCallback(const ConnectionCallback& cb);
    void SetMessageCallback(const MessageCallback& cb);

    void SetThreadNum(int num);

    void start();

    // About connection:
    void NewConnection(int connfd, InetAddress peer_addr);

    void RemoveConnection(const TcpConnectionPtr& conn);

    void RemoveConnectionInLoop(const TcpConnectionPtr& conn);

    ~TcpServer();

private:
    std::string ip_port_;
    std::string name_;
    EventLoop* loop_;
    std::unordered_map<std::string, TcpConnectionPtr> connections_;
    std::unique_ptr<Acceptor> acceptor_;           // mainloop
    std::shared_ptr<LoopThreadPool> thread_pool_;  // one loop per thread

    ConnectionCallback connection_callback_;  // 有新连接时的回调
    MessageCallback message_callback_;        // 有读写事件发生时的回调

    WriteCompleteCallback write_complete_callback_;  // 消息发送完成后的回调
    ThreadInitCallback thread_init_callback;         // loop线程初始化的回调
    HighWaterMarkCallback high_water_mark_callback;  // 高水位

    int next_conn_id;  // auto increase id
    std::atomic_int started_;
};
